package oss

import (
	"TaskAssignmentSystem/pkg/utils"
	"bytes"
	"errors"
	"fmt"
	alioss "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

type BucketClient struct {
	*alioss.Bucket
}

func NewOss() (bucket *BucketClient, err error) {
	// 创建OSSClient实例。
	var client *alioss.Client
	client, err = alioss.New(utils.ServerConf.AliOssConf.EndPoint, utils.ServerConf.AliOssConf.AccessKeyID, utils.ServerConf.AliOssConf.AccessKeySecret)
	if err != nil {
		fmt.Println("Error:", err)
		return nil, err
	}

	// 获取存储空间。
	buckets, err := client.Bucket(utils.ServerConf.AliOssConf.Bucket)
	if err != nil {
		fmt.Println("Error:", err)
		return nil, err
	}
	return &BucketClient{buckets}, err
}

func (B *BucketClient) UpBytes(imgBytes []byte, ObjectName string) (err error) {
	newOss, err := NewOss()
	if err != nil {
		return err
	}
	// 上传Byte数组。
	err = newOss.PutObject(ObjectName, bytes.NewReader(imgBytes))
	if err != nil {
		fmt.Println("Error:", err)
		return err
	}
	return err
}

/*
 * 批量删除文件
 */

func (B *BucketClient) BatchRemoveFiles(filepath string) error {
	newOss, err := NewOss()
	if err != nil {
		return err
	}
	// 列举所有包含指定前缀的文件并删除。
	marker := alioss.Marker("")
	// 如果您需要删除所有前缀为src的文件，则prefix设置为src。设置为src后，所有前缀为src的非目录文件、src目录以及目录下的所有文件均会被删除。
	//prefix := oss.Prefix("src")
	// 如果您仅需要删除src目录及目录下的所有文件，则prefix设置为src/。
	prefix := alioss.Prefix(fmt.Sprintf("%s/", filepath))
	count := 0
	for {
		lor, err := newOss.ListObjects(marker, prefix)
		if err != nil {
			return err
		}

		var objects []string
		for _, object := range lor.Objects {
			objects = append(objects, object.Key)
		}
		// 将oss.DeleteObjectsQuiet设置为true，表示不返回删除结果。
		if len(objects) > 0 {
			delRes, err := newOss.DeleteObjects(objects, alioss.DeleteObjectsQuiet(true))
			if err != nil {
				return err
			}

			if len(delRes.DeletedObjects) > 0 {
				return errors.New(fmt.Sprintf("these objects deleted failure,%v", delRes.DeletedObjects))
			}
		}
		count += len(objects)

		prefix = alioss.Prefix(lor.Prefix)
		marker = alioss.Marker(lor.NextMarker)
		if !lor.IsTruncated {
			break
		}
	}
	return err
}
